package cn.fintecher.pangolin.entity.elastic;

import cn.fintecher.pangolin.common.enums.*;
import cn.fintecher.pangolin.common.utils.Constants;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Auther: xiaqun
 * @Description: 分案策略实体
 * @Date: 15:06 2019/8/30
 */

@Data
@Document(indexName = Constants.STRATEGY, type = Constants.STRATEGY, shards = 1, replicas = 0)
@Api(value = "分案策略实体", description = "分案策略实体")
public class Strategy {
    @Id
    @ApiModelProperty(value = "主键ID")
    private String id;

    @ApiModelProperty(value = "策略名称")
    private String name;

    @ApiModelProperty(value = "公式JSON")
    private String formulaJson;

    @ApiModelProperty(value = "公式")
    private String formula;

    @ApiModelProperty(value = "策略类型")
    private StrategyType strategyType;

    @ApiModelProperty(value = "分配类型")
    private StrategyDistributeType type;

    @ApiModelProperty(value = "优先级")
    private Integer priority;

    @ApiModelProperty(value = "委托方集合")
    private List<String> principalIds;

    @ApiModelProperty(value = "案件类型")
    private CaseType caseType;

    @ApiModelProperty(value = "策略状态")
    private BaseStatus status;

    @ApiModelProperty(value = "是否综合分配")
    private BaseSelect isComplex;

    @ApiModelProperty(value = "分案模型集合")
    private List<CollectorModel> models;

    @ApiModelProperty(value = "创建人")
    private String operator;

    @ApiModelProperty(value = "创建时间")
    private Date operateTime;

    @ApiModelProperty(value = "更新人")
    private String updater;

    @ApiModelProperty(value = "更新时间")
    private Date updateTime;

    public void process(String name, Date date, boolean flag) {
        if (flag) {
            this.operator = name;
            this.operateTime = date;
        }
        this.updater = name;
        this.updateTime = date;
    }

    /**
     * 解析公式
     *
     * @param jsonObject
     * @param stringBuilder
     * @return
     * @throws JSONException
     */
    public void analysisFormula(String jsonObject, StringBuilder stringBuilder) throws JSONException {
        //处理委托方集合
        if (!this.principalIds.isEmpty()) {
            stringBuilder.append("(");
            for (int i = 0; i < this.principalIds.size(); i++) {
                if (i == this.principalIds.size() - 1) {
                    stringBuilder.append((this.strategyType.equals(StrategyType.WAIT_DISTRIBUTE) ? "baseCase.principalId==" : "caseInfo.principalId==")).append("\"").append(this.principalIds.get(i)).append("\"").append(")");
                } else {
                    stringBuilder.append((this.strategyType.equals(StrategyType.WAIT_DISTRIBUTE) ? "baseCase.principalId==" : "caseInfo.principalId==")).append("\"").append(this.principalIds.get(i)).append("\"").append("||");
                }
            }
        }
        //处理案件类型
        if (!this.strategyType.equals(StrategyType.WAIT_DISTRIBUTE)) {
            if (Objects.nonNull(this.caseType)) {
                if (!this.principalIds.isEmpty()) {
                    stringBuilder.append("&&(");
                } else {
                    stringBuilder.append("(");
                }
                stringBuilder.append("caseInfo.caseType==").append("\"").append(this.caseType.name()).append("\"").append(")");
            }
        }
        if (StringUtils.isNotBlank(jsonObject)) {
            if (!this.principalIds.isEmpty()) {
                stringBuilder.append("&&(");
            } else {
                stringBuilder.append("(");
            }
            JSONArray jsonArray = new JSONArray(jsonObject);
            int iSize = jsonArray.length();
            for (int i = 0; i < iSize; i++) {
                JSONObject jsonObj = jsonArray.getJSONObject(i);
                if (jsonObj.getBoolean("leaf")) {
                    stringBuilder.append(processRelation(jsonObj.get("bracket").toString()));
                    if (this.strategyType.equals(StrategyType.WAIT_DISTRIBUTE)) {
                        stringBuilder.append("baseCase.");
                    } else {
                        stringBuilder.append("caseInfo.");
                    }
                    if (jsonObj.get("variable").equals("delegationDate") || jsonObj.get("variable").equals("endCaseDate")) {
                        stringBuilder.append(jsonObj.get("variable")).append(".getTime()");
                    } else {
                        stringBuilder.append(jsonObj.get("variable"));
                    }
                    stringBuilder.append(jsonObj.get("symbol"));
                    if (jsonObj.get("variable").equals("delegationDate") || jsonObj.get("variable").equals("endCaseDate")) {
                        stringBuilder.append(Objects.requireNonNull(ZWDateUtil.getUtilDate(jsonObj.get("value").toString(), "yyyy-MM-dd")).getTime());
                    } else {
                        stringBuilder.append(jsonObj.get("value"));
                    }

                } else {
                    stringBuilder.append(processRelation(jsonObj.get("bracket").toString()));
                    stringBuilder.append("(");
                    analysisFormula(jsonObj.getJSONArray("children").toString(), stringBuilder);
                    stringBuilder.append(")");
                }
            }
            int ii = jsonObject.split("\\(").length;
            int jj = jsonObject.split("\\)").length;
            for (int k = 0; k < ii - jj; k++) {
                stringBuilder.append(")");
            }
            stringBuilder.append(")");
        }
        this.formula = stringBuilder.toString();
    }

    private String processRelation(String str) {
        switch (str) {
            case "并且":
                return "&&";
            case "或者":
                return "||";
            case "并且(":
                return "&&(";
            case "或者(":
                return "||(";
            case ")并且":
                return ")&&";
            case ")或者":
                return ")||";
            case ")并且(":
                return ")&&(";
            case ")或者(":
                return ")||(";
            case "(":
                return "(";
            case ")":
                return ")";
            default:
                return "";
        }
    }
}
